/**
 * Copyright (c) 2008 - TheNittyGritty - Thomas Brekelmans
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package nl.thenittygritty.utils 
{

	/**
	 * ColorUtils is a library class which shouldn't be instantiated. Instead it
	 * provides static methods which help in working with Color values.
	 */
	public class ColorUtils 
	{
		/**
		 * Private constructor for the ColorUtils, this shouldn't be called.
		 */
		public function ColorUtils() 
		{
			// Throw an error here, we shouldn't try to instantiate ColorUtils.
			throw new Error("The ColorUtils shouldn't be instantiated.");
		}

		/**
		 * Performs a linear brightness adjustment of an RGB color.
		 *
		 * @param brightnessOffset Amount to be added to each color channel.
		 * The range for this parameter is -255 to 255; -255 produces black 
		 * while 255 produces white.
		 * If this parameter is 0, the RGB color returned is the same as 
		 * the original color.
		 */
		public static function adjustBrightness(rgb:uint, 
												brightnessOffset:Number):uint
		{
			var r:Number = Math.max(Math.min(((rgb >> 16) & 0xFF) + 
											   brightnessOffset, 255), 0);
			var g:Number = Math.max(Math.min(((rgb >> 8) & 0xFF) + 
											   brightnessOffset, 255), 0);
			var b:Number = Math.max(Math.min((rgb & 0xFF) + brightnessOffset, 
											  255), 0);
		
			return (r << 16) | (g << 8) | b;
		} 

		/**
		 * Performs a scaled brightness adjustment of an RGB color.
		 *
		 * @param brightnessScale The percentage to brighten or darken the 
		 * original color.
		 * If positive, the original color is brightened toward white by 
		 * this percentage. 
		 * If negative, it is darkened toward black by this percentage.
		 * The range for this parameter is -100 to 100; -100 produces black 
		 * while 100 produces white.
		 * If this parameter is 0, the RGB color returned is the same as 
		 * the original color.
		 */
		public static function adjustBrightnessScaled(rgb:uint, 
												brightnessScale:Number):uint
		{
			var r:Number;
			var g:Number;
			var b:Number;
		
			if (brightnessScale == 0)
			return rgb;
		
			if (brightnessScale < 0)
			{
				brightnessScale = (100 + brightnessScale) / 100;
				r = ((rgb >> 16) & 0xFF) * brightnessScale;
				g = ((rgb >> 8) & 0xFF) * brightnessScale;
				b = (rgb & 0xFF) * brightnessScale;
			}
			else // brightnessScale > 0
			{
				brightnessScale /= 100;
				r = ((rgb >> 16) & 0xFF);
				g = ((rgb >> 8) & 0xFF);
				b = (rgb & 0xFF);
			
				r += ((0xFF - r) * brightnessScale);
				g += ((0xFF - g) * brightnessScale);
				b += ((0xFF - b) * brightnessScale);
			
				r = Math.min(r, 255);
				g = Math.min(g, 255);
				b = Math.min(b, 255);
			}
	
			return (r << 16) | (g << 8) | b;
		}

		/**
		 * Performs an RGB multiplication of two RGB colors.
		 *  
		 * <p>This always results in a darker number than either original color 
		 * unless one of them is white, in which case the other color 
		 * is returned.</p>
		 */
		public static function rgbMultiply(rgb1:uint, rgb2:uint):uint
		{
			var r1:Number = (rgb1 >> 16) & 0xFF;
			var g1:Number = (rgb1 >> 8) & 0xFF;
			var b1:Number = rgb1 & 0xFF;
		
			var r2:Number = (rgb2 >> 16) & 0xFF;
			var g2:Number = (rgb2 >> 8) & 0xFF;
			var b2:Number = rgb2 & 0xFF;
		
			return ((r1 * r2 / 255) << 16) | ((g1 * g2 / 255) << 8) | 
				   (b1 * b2 / 255);
		}
	}
}
